﻿using Microsoft.Extensions.Logging;
using ServoDrivesLibAbstract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ServoDrivesLib.Controls
{
    public abstract class CardControl : IServoControl, IEtherCATMode, IControlCard
    {
        public abstract IEtherCATMode EtherCATControl { get; }
        public abstract IServoControl ServoControl { get; }
        internal abstract ILogger? Logger { get; }
        public abstract int ClearAxisError(int axis);
        public abstract int ClearErrorCode();
        public abstract int ClearPosition(int axis);
        public abstract int Close();
        public abstract int DownloadMemFile();
        public abstract int EndScan();
        public abstract int GetAxisError(int axis, ref int error);
        public abstract int GetAxisMoveStatus(int axis);
        public abstract int GetAxisNums(ref int axisNums);
        public abstract int GetAxisSpeed(int axis, ref double speed);
        public abstract int GetAxisStatus(int axis, ref int status);
        public abstract int GetAxisType(int axis, ref int type);
        public abstract int GetEncoderUnit(int axis, ref double encoder);
        public abstract int GetEquiv(int axis, ref double equip);
        public abstract int GetErrorCode(ref int code);
        public abstract int GetEtherCATConsumeTime(ref ulong averageTime, ref ulong maxTime, ref ulong cycles);
        public abstract int GetHomeMove(int axis, ref int status);
        public abstract int GetProFile(int axis, ref double minSpeed, ref double maxSpeed, ref double tAcc, ref double tDec, ref double stopSpeed, ref double sramp);
        public abstract int GetSlaveValue(ref int slaveValue);
        public abstract int Init();
        public abstract int MoveAxis(int axis, double position);
        public abstract int MoveAxisAbs(int axis, double position);
        public abstract int MoveStop(int axis);
        public abstract int PDORead(int slave, int index, int subIndex, int valueLength, ref int value);
        public abstract int PDOWrite(int slave, int index, int subIndex, int valueLength, int value);
        public abstract int Rest(CardResetStatus status);
        public abstract int SDORead(int slave, int index, int subIndex, int valueLength, ref int value);
        public abstract int SDOWrite(int slave, int index, int subIndex, int valueLength, int value);
        public abstract int SetAxisDisable(int axis);
        public abstract int SetAxisEnable(int axis);
        public abstract int SetCycleTime(int cycleTime);
        public abstract int SetEquiv(int axis, double equip);
        public abstract int SetHomeMove(int axis);
        public abstract int SetProFile(int axis, double minSpeed, double maxSpeed, double tAcc, double tDec, double stopSpeed, double sramp);
        public abstract int StartScan();
        public abstract int StopEtherCAT();

        public virtual void CopyDll(string dllName)
        {
            var codeBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            Directory.EnumerateFiles(Path.Combine(codeBase, "Library"), dllName, SearchOption.AllDirectories).ToList().ForEach(x =>
            {
                string str = "";
                if (Environment.Is64BitOperatingSystem)
                {
                    str = "64";
                }
                else
                {
                    str = "32";
                }
                if (x.Contains(str))
                    File.Copy(x, Path.Combine(codeBase, Path.GetFileName(x)), true);
            });
        }

        internal virtual void LogMessage(string message,
           [CallerMemberName] string stringpropertyName = "",
           [CallerLineNumber] int line = 0)
        {
            Logger?.LogInformation("Line:{0} {1}={2}", line, stringpropertyName, message);
        }
    }
}
